/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package kimo.persistence.controllers;

import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import kimo.persistence.entities.UnitLocationType;
import kimo.persistence.entities.Municipality;
import kimo.persistence.entities.AdtType;
import kimo.persistence.entities.Sex;
import kimo.persistence.entities.Daok;
import kimo.persistence.entities.Pcheck;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import kimo.persistence.controllers.exceptions.IllegalOrphanException;
import kimo.persistence.controllers.exceptions.NonexistentEntityException;
import kimo.persistence.entities.Producer;
import kimo.persistence.entities.Production;

/**
 *
 * @author a381u296
 */
public class ProducerJpaController implements Serializable {

    public ProducerJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Producer producer) {
        if (producer.getPcheckList() == null) {
            producer.setPcheckList(new ArrayList<Pcheck>());
        }
        if (producer.getProductionList() == null) {
            producer.setProductionList(new ArrayList<Production>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            UnitLocationType producerUnitLocationTypeId = producer.getProducerUnitLocationTypeId();
            if (producerUnitLocationTypeId != null) {
                producerUnitLocationTypeId = em.getReference(producerUnitLocationTypeId.getClass(), producerUnitLocationTypeId.getUnitLocationTypeId());
                producer.setProducerUnitLocationTypeId(producerUnitLocationTypeId);
            }
            Municipality producerRuralMunicipalityId = producer.getProducerRuralMunicipalityId();
            if (producerRuralMunicipalityId != null) {
                producerRuralMunicipalityId = em.getReference(producerRuralMunicipalityId.getClass(), producerRuralMunicipalityId.getMunicipalityId());
                producer.setProducerRuralMunicipalityId(producerRuralMunicipalityId);
            }
            Municipality producerMunicipalityId = producer.getProducerMunicipalityId();
            if (producerMunicipalityId != null) {
                producerMunicipalityId = em.getReference(producerMunicipalityId.getClass(), producerMunicipalityId.getMunicipalityId());
                producer.setProducerMunicipalityId(producerMunicipalityId);
            }
            AdtType producerAdtTypeId = producer.getProducerAdtTypeId();
            if (producerAdtTypeId != null) {
                producerAdtTypeId = em.getReference(producerAdtTypeId.getClass(), producerAdtTypeId.getAdtTypeId());
                producer.setProducerAdtTypeId(producerAdtTypeId);
            }
            Sex producerSexId = producer.getProducerSexId();
            if (producerSexId != null) {
                producerSexId = em.getReference(producerSexId.getClass(), producerSexId.getSexId());
                producer.setProducerSexId(producerSexId);
            }
            Daok producerDaokCd = producer.getProducerDaokCd();
            if (producerDaokCd != null) {
                producerDaokCd = em.getReference(producerDaokCd.getClass(), producerDaokCd.getDaokCd());
                producer.setProducerDaokCd(producerDaokCd);
            }
            List<Pcheck> attachedPcheckList = new ArrayList<Pcheck>();
            for (Pcheck pcheckListPcheckToAttach : producer.getPcheckList()) {
                pcheckListPcheckToAttach = em.getReference(pcheckListPcheckToAttach.getClass(), pcheckListPcheckToAttach.getCheckId());
                attachedPcheckList.add(pcheckListPcheckToAttach);
            }
            producer.setPcheckList(attachedPcheckList);
            List<Production> attachedProductionList = new ArrayList<Production>();
            for (Production productionListProductionToAttach : producer.getProductionList()) {
                productionListProductionToAttach = em.getReference(productionListProductionToAttach.getClass(), productionListProductionToAttach.getProductionId());
                attachedProductionList.add(productionListProductionToAttach);
            }
            producer.setProductionList(attachedProductionList);
            em.persist(producer);
            if (producerUnitLocationTypeId != null) {
                producerUnitLocationTypeId.getProducerList().add(producer);
                producerUnitLocationTypeId = em.merge(producerUnitLocationTypeId);
            }
            if (producerRuralMunicipalityId != null) {
                producerRuralMunicipalityId.getProducerList().add(producer);
                producerRuralMunicipalityId = em.merge(producerRuralMunicipalityId);
            }
            if (producerMunicipalityId != null) {
                producerMunicipalityId.getProducerList().add(producer);
                producerMunicipalityId = em.merge(producerMunicipalityId);
            }
            if (producerAdtTypeId != null) {
                producerAdtTypeId.getProducerList().add(producer);
                producerAdtTypeId = em.merge(producerAdtTypeId);
            }
            if (producerSexId != null) {
                producerSexId.getProducerList().add(producer);
                producerSexId = em.merge(producerSexId);
            }
            if (producerDaokCd != null) {
                producerDaokCd.getProducerList().add(producer);
                producerDaokCd = em.merge(producerDaokCd);
            }
            for (Pcheck pcheckListPcheck : producer.getPcheckList()) {
                Producer oldCheckProducerIdOfPcheckListPcheck = pcheckListPcheck.getCheckProducerId();
                pcheckListPcheck.setCheckProducerId(producer);
                pcheckListPcheck = em.merge(pcheckListPcheck);
                if (oldCheckProducerIdOfPcheckListPcheck != null) {
                    oldCheckProducerIdOfPcheckListPcheck.getPcheckList().remove(pcheckListPcheck);
                    oldCheckProducerIdOfPcheckListPcheck = em.merge(oldCheckProducerIdOfPcheckListPcheck);
                }
            }
            for (Production productionListProduction : producer.getProductionList()) {
                Producer oldProductionProducerIdOfProductionListProduction = productionListProduction.getProductionProducerId();
                productionListProduction.setProductionProducerId(producer);
                productionListProduction = em.merge(productionListProduction);
                if (oldProductionProducerIdOfProductionListProduction != null) {
                    oldProductionProducerIdOfProductionListProduction.getProductionList().remove(productionListProduction);
                    oldProductionProducerIdOfProductionListProduction = em.merge(oldProductionProducerIdOfProductionListProduction);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Producer producer) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Producer persistentProducer = em.find(Producer.class, producer.getProducerId());
            UnitLocationType producerUnitLocationTypeIdOld = persistentProducer.getProducerUnitLocationTypeId();
            UnitLocationType producerUnitLocationTypeIdNew = producer.getProducerUnitLocationTypeId();
            Municipality producerRuralMunicipalityIdOld = persistentProducer.getProducerRuralMunicipalityId();
            Municipality producerRuralMunicipalityIdNew = producer.getProducerRuralMunicipalityId();
            Municipality producerMunicipalityIdOld = persistentProducer.getProducerMunicipalityId();
            Municipality producerMunicipalityIdNew = producer.getProducerMunicipalityId();
            AdtType producerAdtTypeIdOld = persistentProducer.getProducerAdtTypeId();
            AdtType producerAdtTypeIdNew = producer.getProducerAdtTypeId();
            Sex producerSexIdOld = persistentProducer.getProducerSexId();
            Sex producerSexIdNew = producer.getProducerSexId();
            Daok producerDaokCdOld = persistentProducer.getProducerDaokCd();
            Daok producerDaokCdNew = producer.getProducerDaokCd();
            List<Pcheck> pcheckListOld = persistentProducer.getPcheckList();
            List<Pcheck> pcheckListNew = producer.getPcheckList();
            List<Production> productionListOld = persistentProducer.getProductionList();
            List<Production> productionListNew = producer.getProductionList();
            List<String> illegalOrphanMessages = null;
            for (Pcheck pcheckListOldPcheck : pcheckListOld) {
                if (!pcheckListNew.contains(pcheckListOldPcheck)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Pcheck " + pcheckListOldPcheck + " since its checkProducerId field is not nullable.");
                }
            }
            for (Production productionListOldProduction : productionListOld) {
                if (!productionListNew.contains(productionListOldProduction)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Production " + productionListOldProduction + " since its productionProducerId field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (producerUnitLocationTypeIdNew != null) {
                producerUnitLocationTypeIdNew = em.getReference(producerUnitLocationTypeIdNew.getClass(), producerUnitLocationTypeIdNew.getUnitLocationTypeId());
                producer.setProducerUnitLocationTypeId(producerUnitLocationTypeIdNew);
            }
            if (producerRuralMunicipalityIdNew != null) {
                producerRuralMunicipalityIdNew = em.getReference(producerRuralMunicipalityIdNew.getClass(), producerRuralMunicipalityIdNew.getMunicipalityId());
                producer.setProducerRuralMunicipalityId(producerRuralMunicipalityIdNew);
            }
            if (producerMunicipalityIdNew != null) {
                producerMunicipalityIdNew = em.getReference(producerMunicipalityIdNew.getClass(), producerMunicipalityIdNew.getMunicipalityId());
                producer.setProducerMunicipalityId(producerMunicipalityIdNew);
            }
            if (producerAdtTypeIdNew != null) {
                producerAdtTypeIdNew = em.getReference(producerAdtTypeIdNew.getClass(), producerAdtTypeIdNew.getAdtTypeId());
                producer.setProducerAdtTypeId(producerAdtTypeIdNew);
            }
            if (producerSexIdNew != null) {
                producerSexIdNew = em.getReference(producerSexIdNew.getClass(), producerSexIdNew.getSexId());
                producer.setProducerSexId(producerSexIdNew);
            }
            if (producerDaokCdNew != null) {
                producerDaokCdNew = em.getReference(producerDaokCdNew.getClass(), producerDaokCdNew.getDaokCd());
                producer.setProducerDaokCd(producerDaokCdNew);
            }
            List<Pcheck> attachedPcheckListNew = new ArrayList<Pcheck>();
            for (Pcheck pcheckListNewPcheckToAttach : pcheckListNew) {
                pcheckListNewPcheckToAttach = em.getReference(pcheckListNewPcheckToAttach.getClass(), pcheckListNewPcheckToAttach.getCheckId());
                attachedPcheckListNew.add(pcheckListNewPcheckToAttach);
            }
            pcheckListNew = attachedPcheckListNew;
            producer.setPcheckList(pcheckListNew);
            List<Production> attachedProductionListNew = new ArrayList<Production>();
            for (Production productionListNewProductionToAttach : productionListNew) {
                productionListNewProductionToAttach = em.getReference(productionListNewProductionToAttach.getClass(), productionListNewProductionToAttach.getProductionId());
                attachedProductionListNew.add(productionListNewProductionToAttach);
            }
            productionListNew = attachedProductionListNew;
            producer.setProductionList(productionListNew);
            producer = em.merge(producer);
            if (producerUnitLocationTypeIdOld != null && !producerUnitLocationTypeIdOld.equals(producerUnitLocationTypeIdNew)) {
                producerUnitLocationTypeIdOld.getProducerList().remove(producer);
                producerUnitLocationTypeIdOld = em.merge(producerUnitLocationTypeIdOld);
            }
            if (producerUnitLocationTypeIdNew != null && !producerUnitLocationTypeIdNew.equals(producerUnitLocationTypeIdOld)) {
                producerUnitLocationTypeIdNew.getProducerList().add(producer);
                producerUnitLocationTypeIdNew = em.merge(producerUnitLocationTypeIdNew);
            }
            if (producerRuralMunicipalityIdOld != null && !producerRuralMunicipalityIdOld.equals(producerRuralMunicipalityIdNew)) {
                producerRuralMunicipalityIdOld.getProducerList().remove(producer);
                producerRuralMunicipalityIdOld = em.merge(producerRuralMunicipalityIdOld);
            }
            if (producerRuralMunicipalityIdNew != null && !producerRuralMunicipalityIdNew.equals(producerRuralMunicipalityIdOld)) {
                producerRuralMunicipalityIdNew.getProducerList().add(producer);
                producerRuralMunicipalityIdNew = em.merge(producerRuralMunicipalityIdNew);
            }
            if (producerMunicipalityIdOld != null && !producerMunicipalityIdOld.equals(producerMunicipalityIdNew)) {
                producerMunicipalityIdOld.getProducerList().remove(producer);
                producerMunicipalityIdOld = em.merge(producerMunicipalityIdOld);
            }
            if (producerMunicipalityIdNew != null && !producerMunicipalityIdNew.equals(producerMunicipalityIdOld)) {
                producerMunicipalityIdNew.getProducerList().add(producer);
                producerMunicipalityIdNew = em.merge(producerMunicipalityIdNew);
            }
            if (producerAdtTypeIdOld != null && !producerAdtTypeIdOld.equals(producerAdtTypeIdNew)) {
                producerAdtTypeIdOld.getProducerList().remove(producer);
                producerAdtTypeIdOld = em.merge(producerAdtTypeIdOld);
            }
            if (producerAdtTypeIdNew != null && !producerAdtTypeIdNew.equals(producerAdtTypeIdOld)) {
                producerAdtTypeIdNew.getProducerList().add(producer);
                producerAdtTypeIdNew = em.merge(producerAdtTypeIdNew);
            }
            if (producerSexIdOld != null && !producerSexIdOld.equals(producerSexIdNew)) {
                producerSexIdOld.getProducerList().remove(producer);
                producerSexIdOld = em.merge(producerSexIdOld);
            }
            if (producerSexIdNew != null && !producerSexIdNew.equals(producerSexIdOld)) {
                producerSexIdNew.getProducerList().add(producer);
                producerSexIdNew = em.merge(producerSexIdNew);
            }
            if (producerDaokCdOld != null && !producerDaokCdOld.equals(producerDaokCdNew)) {
                producerDaokCdOld.getProducerList().remove(producer);
                producerDaokCdOld = em.merge(producerDaokCdOld);
            }
            if (producerDaokCdNew != null && !producerDaokCdNew.equals(producerDaokCdOld)) {
                producerDaokCdNew.getProducerList().add(producer);
                producerDaokCdNew = em.merge(producerDaokCdNew);
            }
            for (Pcheck pcheckListNewPcheck : pcheckListNew) {
                if (!pcheckListOld.contains(pcheckListNewPcheck)) {
                    Producer oldCheckProducerIdOfPcheckListNewPcheck = pcheckListNewPcheck.getCheckProducerId();
                    pcheckListNewPcheck.setCheckProducerId(producer);
                    pcheckListNewPcheck = em.merge(pcheckListNewPcheck);
                    if (oldCheckProducerIdOfPcheckListNewPcheck != null && !oldCheckProducerIdOfPcheckListNewPcheck.equals(producer)) {
                        oldCheckProducerIdOfPcheckListNewPcheck.getPcheckList().remove(pcheckListNewPcheck);
                        oldCheckProducerIdOfPcheckListNewPcheck = em.merge(oldCheckProducerIdOfPcheckListNewPcheck);
                    }
                }
            }
            for (Production productionListNewProduction : productionListNew) {
                if (!productionListOld.contains(productionListNewProduction)) {
                    Producer oldProductionProducerIdOfProductionListNewProduction = productionListNewProduction.getProductionProducerId();
                    productionListNewProduction.setProductionProducerId(producer);
                    productionListNewProduction = em.merge(productionListNewProduction);
                    if (oldProductionProducerIdOfProductionListNewProduction != null && !oldProductionProducerIdOfProductionListNewProduction.equals(producer)) {
                        oldProductionProducerIdOfProductionListNewProduction.getProductionList().remove(productionListNewProduction);
                        oldProductionProducerIdOfProductionListNewProduction = em.merge(oldProductionProducerIdOfProductionListNewProduction);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = producer.getProducerId();
                if (findProducer(id) == null) {
                    throw new NonexistentEntityException("The producer with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Producer producer;
            try {
                producer = em.getReference(Producer.class, id);
                producer.getProducerId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The producer with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Pcheck> pcheckListOrphanCheck = producer.getPcheckList();
            for (Pcheck pcheckListOrphanCheckPcheck : pcheckListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Producer (" + producer + ") cannot be destroyed since the Pcheck " + pcheckListOrphanCheckPcheck + " in its pcheckList field has a non-nullable checkProducerId field.");
            }
            List<Production> productionListOrphanCheck = producer.getProductionList();
            for (Production productionListOrphanCheckProduction : productionListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Producer (" + producer + ") cannot be destroyed since the Production " + productionListOrphanCheckProduction + " in its productionList field has a non-nullable productionProducerId field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            UnitLocationType producerUnitLocationTypeId = producer.getProducerUnitLocationTypeId();
            if (producerUnitLocationTypeId != null) {
                producerUnitLocationTypeId.getProducerList().remove(producer);
                producerUnitLocationTypeId = em.merge(producerUnitLocationTypeId);
            }
            Municipality producerRuralMunicipalityId = producer.getProducerRuralMunicipalityId();
            if (producerRuralMunicipalityId != null) {
                producerRuralMunicipalityId.getProducerList().remove(producer);
                producerRuralMunicipalityId = em.merge(producerRuralMunicipalityId);
            }
            Municipality producerMunicipalityId = producer.getProducerMunicipalityId();
            if (producerMunicipalityId != null) {
                producerMunicipalityId.getProducerList().remove(producer);
                producerMunicipalityId = em.merge(producerMunicipalityId);
            }
            AdtType producerAdtTypeId = producer.getProducerAdtTypeId();
            if (producerAdtTypeId != null) {
                producerAdtTypeId.getProducerList().remove(producer);
                producerAdtTypeId = em.merge(producerAdtTypeId);
            }
            Sex producerSexId = producer.getProducerSexId();
            if (producerSexId != null) {
                producerSexId.getProducerList().remove(producer);
                producerSexId = em.merge(producerSexId);
            }
            Daok producerDaokCd = producer.getProducerDaokCd();
            if (producerDaokCd != null) {
                producerDaokCd.getProducerList().remove(producer);
                producerDaokCd = em.merge(producerDaokCd);
            }
            em.remove(producer);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Producer> findProducerEntities() {
        return findProducerEntities(true, -1, -1);
    }

    public List<Producer> findProducerEntities(int maxResults, int firstResult) {
        return findProducerEntities(false, maxResults, firstResult);
    }

    private List<Producer> findProducerEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Producer.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Producer findProducer(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Producer.class, id);
        } finally {
            em.close();
        }
    }

    public int getProducerCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Producer> rt = cq.from(Producer.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
